home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume20 / etherlib / part02 < prev    next >
Encoding:
Internet Message Format  |  1989-10-24  |  56.2 KB

  1. Subject:  v20i059:  User-level interface to Ethernet, Part02/03
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Alexander Dupuy <dupuy@cs.columbia.edu>
  7. Posting-number: Volume 20, Issue 59
  8. Archive-name: etherlib/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 2 (of 3)."
  17. # Contents:  ./GNUmake.mk ./Instructions ./SunBugs
  18. #   ./src/Makefile ./src/dliopen.c ./src/enetopen.c ./src/ether.h
  19. #   ./src/etherarp.c ./src/ethere2h.c ./src/ethere2ip.c
  20. #   ./src/etherh2e.c ./src/etherhe2e.c ./src/etherints.c
  21. #   ./src/etherip2e.c ./tests/ctp.h
  22. # Wrapped by rsalz@papaya.bbn.com on Wed Oct 25 16:37:31 1989
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f './GNUmake.mk' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'./GNUmake.mk'\"
  26. else
  27. echo shar: Extracting \"'./GNUmake.mk'\" \(3104 characters\)
  28. sed "s/^X//" >'./GNUmake.mk' <<'END_OF_FILE'
  29. X#
  30. X# Indirect GNU makefile for ethernet interface library
  31. X#
  32. X
  33. X# Get pattern rules for %.ps
  34. X
  35. Xinclude ../GNUmake.config
  36. X
  37. X# This builds machine-dependent components for the ethernet interface library
  38. X
  39. X# VPATH directives
  40. X
  41. Xvpath %.h ../src
  42. Xvpath %.c ../src:../tests
  43. Xvpath %.3n ..
  44. X
  45. X
  46. X# Configuration
  47. X
  48. XNIT := $(shell ls /usr/include/net/nit.h 2>/dev/null)
  49. XNIT4 := $(shell ls /dev/nit 2>/dev/null)
  50. XENET := $(shell ls /dev/enet/ 2>/dev/null)
  51. X
  52. X# Software components
  53. X
  54. XHDRS = ether.h libether.h
  55. X
  56. XSRCS = etheraddr.c etherints.c ethere2a.c ethera2e.c etherarp.c etherlocal.c \
  57. X ethere2ip.c etherip2e.c ethere2h.c etherh2e.c etherhe2e.c
  58. X
  59. XALLSRCS := $(SRCS) \
  60. X etherblock.c etherread.c etherreadv.c nitaddr.c \
  61. X nit4self.c nit4intaddr.c nit4open.c nit4write.c nit4writev.c \
  62. X nit3self.c nit3intaddr.c nit3open.c \
  63. X nit3read.c nit3readv.c nit3write.c nit3writev.c \
  64. X dliaddr.c dliself.c dliintaddr.c dliopen.c \
  65. X dliread.c dlireadv.c dliwrite.c dliwritev.c \
  66. X enetblock.c enetaddr.c enetself.c enetintaddr.c enetopen.c \
  67. X enetwrite.c enetwritev.c
  68. X
  69. Xifneq ($(NIT4),)
  70. XSRCS := $(SRCS) etherblock.c etherread.c etherreadv.c \
  71. X nitaddr.c nit4self.c nit4intaddr.c nit4open.c nit4write.c nit4writev.c
  72. XDEFINES := $(DEFINES) -DETHERDB
  73. Xelse
  74. Xifneq ($(NIT),)
  75. XSRCS := $(SRCS) etherblock.c nitaddr.c nit3self.c nit3intaddr.c \
  76. X nit3open.c nit3read.c nit3readv.c nit3write.c nit3writev.c
  77. XDEFINES := $(DEFINES) -DETHERDB
  78. Xendif
  79. Xendif
  80. X
  81. Xifneq ($(findstring ultrix,$(SYSTEM)),)
  82. XSRCS := $(SRCS) etherblock.c dliaddr.c dliself.c dliintaddr.c \
  83. X dliopen.c dliread.c dlireadv.c dliwrite.c dliwritev.c
  84. XDEFINES := $(DEFINES) -DETHERDB
  85. Xelse
  86. Xifneq ($(ENET),)
  87. XSRCS := $(SRCS) etherread.c etherreadv.c enetblock.c enetaddr.c \
  88. X enetintaddr.c enetself.c enetopen.c enetwrite.c enetwritev.c
  89. X#INCLUDES = -I../enet/4.3
  90. Xendif
  91. Xendif
  92. X
  93. X# Compilation flags used
  94. X
  95. Xifeq ($(findstring gcc,$(CC)),)
  96. X
  97. XCFLAGS = $(OPT) $(DEFINES) $(INCLUDES)
  98. X
  99. Xelse
  100. X
  101. XCFLAGS = $(OPTG) $(DEFINES) $(INCLUDES)
  102. X
  103. Xendif
  104. X
  105. XINCLUDES := -I../src $(INCLUDES)
  106. X
  107. XOBJS = $(SRCS:.c=.o)
  108. X
  109. XLINTFLAGS = -bhuxz
  110. X
  111. X# Default dependency - remake all out of date object files
  112. X
  113. X.PHONY: default all
  114. X
  115. Xdefault: all
  116. X
  117. Xall: libether.a
  118. X
  119. Xlibether.a: $(OBJS)
  120. Xifeq ($(findstring t,$(MAKEFLAGS)),)
  121. X    ar curv $@ $(OBJS)
  122. X    ranlib $@
  123. Xelse
  124. X    @echo $(MAKE) > /dev/null
  125. X    touch $@
  126. X    ranlib -t $@
  127. Xendif
  128. X
  129. Xetheraddr.o: etheraddr.c
  130. X    $(CC) $(CFLAGS) -R -c $< $(OUTPUT_OPTION)
  131. X
  132. Xtest: ethertest
  133. X    ./ethertest
  134. X
  135. Xethertest: ethertest.o libether.a
  136. X
  137. Xctp: ctp.o $(LIBDIR)/libether.a
  138. X
  139. X$(OBJS): $(HDRS)
  140. X
  141. X
  142. X# Installation
  143. X
  144. Xinstall: $(LIBDIR)/libether.a $(INCDIR)/ether.h $(MANDIR)/man3/ether.3n
  145. X
  146. X# Fluff test
  147. X
  148. X.PHONY: lint
  149. X
  150. Xlint: $(SRCS) ethertest.c
  151. X    -$(LINT) $(LINTFLAGS) $(DEFINES) $(INCLUDES) -I. $?
  152. X
  153. X
  154. X# Vgrind formatted listing
  155. X
  156. XLISTS = $(ALLSRCS:.c=.ps) $(HDRS:.h=.ps) index.ps
  157. X
  158. X.PHONY: listing
  159. X
  160. Xlisting: index $(LISTS)
  161. X
  162. Xindex.ps: index
  163. X    sort -fu -o index index
  164. X    $(VGRIND) -t -x index > index.ps
  165. X
  166. Xindex: /dev/null
  167. X    ctags -tv $(SRCS) $(HDRS) >> index 2>/dev/null
  168. X
  169. X
  170. X# Utility operations
  171. X
  172. X.PHONY: clean cleanlists realclean
  173. X
  174. Xclean:
  175. X    rm -f $(OBJS) libether.a ethertest.o ethertest ctp.o ctp
  176. X
  177. Xcleanlists:
  178. X    rm -f $(LISTS) index
  179. X
  180. Xrealclean: clean cleanlists
  181. END_OF_FILE
  182. if test 3104 -ne `wc -c <'./GNUmake.mk'`; then
  183.     echo shar: \"'./GNUmake.mk'\" unpacked with wrong size!
  184. fi
  185. # end of './GNUmake.mk'
  186. fi
  187. if test -f './Instructions' -a "${1}" != "-c" ; then 
  188.   echo shar: Will not clobber existing file \"'./Instructions'\"
  189. else
  190. echo shar: Extracting \"'./Instructions'\" \(2921 characters\)
  191. sed "s/^X//" >'./Instructions' <<'END_OF_FILE'
  192. X
  193. XThis ethernet access library is a part of the Columbia Netmate project which is
  194. Xbeing released as a useful component in its own right.
  195. X
  196. XThese functions provide access to the raw ethernet for user-level programs.  On
  197. XSuns, they are implemented using NIT(4p) (network interface tap).  While they
  198. Xdo not provide the full functionality of NIT, these functions do run on both
  199. Xthe socket- and streams-based NIT implementations.  On Ultrix systems, they are
  200. Ximplemented using DLI (data link interface).  On Berkeley systems, they are
  201. Ximplemented using the Stanford enetfilter available as user-contributed
  202. Xsoftware in the 4.3 BSD release.
  203. X
  204. XThese functions are not designed to be used for ethernet monitoring, but rather
  205. Xfor programs implementing ethernet protocols such as RARP, or the Ethernet
  206. Xconfiguration test protocol.
  207. X
  208. XIt comes with a manual page, and both a GNU makefile and a regular one.
  209. X
  210. XIf you are on a BSD system with the enetfilter, you will have to create some
  211. Xnew device files before you can build or use this library.  Because there is no
  212. Xway to map between the interface names ("il0", "de0", etc.) used by most
  213. Xprograms and the old enetfilter device names (/dev/enet0, /dev/eneta0, etc.),
  214. Xthis library uses a different convention for enetfilter device names, using
  215. Xdevice files in the /dev/enet/ directory.
  216. X
  217. XTherefore, you should create or link an enetfilter device in /dev/enet for each
  218. Xethernet interface, with names like /dev/enet/il0, /dev/enet/de0, etc.  The
  219. Xminor device numbers for these files will correspond to the order in which they
  220. Xare found by the kernel.  This order is the same as in the config file, except
  221. Xthat devices configured into the kernel but not present are not counted.  You
  222. Xcan look at the kernel startup messages in /usr/adm/messages to see the order
  223. Xof ethernet devices; the ethernet addresses are also printed out there, and you
  224. Xcan check those against the results of the ethertest program here.
  225. X
  226. XIf you have GNU make, you should be able to say "gmake" in this directory, and
  227. Xit will build the library for your system in a subdirectory.  You may want to
  228. Xedit the GNUmake.config file to specify various options (such as installation
  229. Xdirectories, cc vs. gcc, etc.)  Once you are satisfied that it has built
  230. Xcorrectly, you can say "gmake install".
  231. X
  232. XIf you don't have GNU make, you will have to cd to the src subdirectory, and
  233. Xedit the Makefile there to reflect your system configuration.  Once you have
  234. Xdone this, you can say "make" to build the library, and "make install" to
  235. Xinstall it.
  236. X
  237. XIf you encounter bugs, or are interested in porting this library to another
  238. Xethernet access interface, please contact me.
  239. X
  240. XAlexander Dupuy
  241. X480 C.S.B.
  242. XComputer Science Dept.
  243. XColumbia University
  244. XNew York City 10027-6699
  245. X
  246. X<dupuy@cs.columbia.edu>
  247. X!rutgers!cs.columbia.edu!dupuy
  248. X
  249. XThis library can be obtained via anonymous FTP from columbia.edu or
  250. Xcs.columbia.edu, in the file pub/etherlib.tar.Z.
  251. X
  252. END_OF_FILE
  253. if test 2921 -ne `wc -c <'./Instructions'`; then
  254.     echo shar: \"'./Instructions'\" unpacked with wrong size!
  255. fi
  256. # end of './Instructions'
  257. fi
  258. if test -f './SunBugs' -a "${1}" != "-c" ; then 
  259.   echo shar: Will not clobber existing file \"'./SunBugs'\"
  260. else
  261. echo shar: Extracting \"'./SunBugs'\" \(1962 characters\)
  262. sed "s/^X//" >'./SunBugs' <<'END_OF_FILE'
  263. XThis is a description of a bug in SunOS 4.0 NIT, which is not fixed in 4.0.3
  264. X
  265. X1016994: Public Summary:
  266. X1016994:    The ifpromisc() routine of net/if.c, which handles
  267. X1016994:    transitions into and out of promiscuous mode by
  268. X1016994:    keeping track of the number of outstanding requests
  269. X1016994:    there are for the mode and calling the interface driver
  270. X1016994:    to change mode on transitions to and from zero
  271. X1016994:    has a bug that causes it to disable promiscuous
  272. X1016994:    mode whenever it is called to disable the mode and
  273. X1016994:    the number of outstanding requests for the mode is
  274. X1016994:    greater than one.
  275. X1016994:    The problem occurs only when there are more than one
  276. X1016994:    concurrent requesters for promiscuous mode for a
  277. X1016994:    particular interface (i.e. run multiple etherfind's
  278. X1016994:    on the same interface in parallel, then terminate
  279. X1016994:    one of the processes).
  280. X1016994: Hook 2:  Needs investigation in release: 4.0.4, 4.0.4c
  281. X
  282. XThis can cause interfaces to go out of promiscuous mode when they shouldn't;
  283. Xpromiscuous mode reception may fail as a result.  This also impacts the
  284. Xreception of multicast addresses with this library, since that is implemented
  285. Xon Suns with promiscuous mode reception and filtering.
  286. X
  287. XThe only workaround seems to be to close all promiscuous mode file descriptors
  288. Xin all processes, then reopen them.  Just setting the IFF_PROMISC bit with a
  289. XSIOCSIFFLAGS ioctl doesn't seem to help.
  290. X
  291. X
  292. X
  293. XThis is a description of a bug in SunOS 4.0.3 NIT.
  294. X
  295. XThe NIT interface now receives broadcast packets sent from the local machine,
  296. Xbut their ethernet source field will sometimes contain a random value.  The
  297. Xpackets as sent out on the ethernet are correct, but the NIT interface
  298. Xsometimes receives them incorrectly.
  299. X
  300. XYou can tell if this bug affects you by running "etherfind -p -arp" and then
  301. Xpinging a nonexistent (or down) host.  If you have the bug, you will see lots
  302. Xof arp packets from strange hosts.  There is no known workaround.
  303. END_OF_FILE
  304. if test 1962 -ne `wc -c <'./SunBugs'`; then
  305.     echo shar: \"'./SunBugs'\" unpacked with wrong size!
  306. fi
  307. # end of './SunBugs'
  308. fi
  309. if test -f './src/Makefile' -a "${1}" != "-c" ; then 
  310.   echo shar: Will not clobber existing file \"'./src/Makefile'\"
  311. else
  312. echo shar: Extracting \"'./src/Makefile'\" \(3830 characters\)
  313. sed "s/^X//" >'./src/Makefile' <<'END_OF_FILE'
  314. X#
  315. X# makefile for ethernet library
  316. X#
  317. X
  318. X# Compilation variables & flags
  319. X
  320. X#CC = gcc
  321. X
  322. X#
  323. X# Sun-3 floating-point options; replace 68881 with soft or fpa as appropriate
  324. X#
  325. X
  326. X#FLOAT_OPTION = f68881
  327. X
  328. XOPT = -O
  329. XOPTG = -g -O -W
  330. X
  331. XDEFINES = 
  332. XINCLUDES = -I. # -I../enet/4.3
  333. X
  334. X# Listing variables and flags
  335. X
  336. XTROFF = ptroff
  337. XVGRIND = vgrind
  338. X
  339. X
  340. X# Suffix rules
  341. X
  342. X.SUFFIXES: .ps
  343. X
  344. X.c.ps:
  345. X    $(VGRIND) -lC -t $< > $@
  346. X
  347. X.h.ps:
  348. X    $(VGRIND) -lC -t $< > $@
  349. X
  350. X
  351. X# Installation tools
  352. X
  353. XINSTALL=install -c
  354. X
  355. XRANLIB=ranlib
  356. X#RANLIB=ranlib -t
  357. X
  358. X
  359. X# Installation locations
  360. X
  361. XMANDIR = /usr/local/man
  362. XBINDIR = /usr/local/bin
  363. XLIBDIR = /usr/local/lib
  364. XINCDIR = /usr/local/include
  365. X
  366. XCFLAGS = $(OPT) $(DEFINES) $(INCLUDES)
  367. X#CFLAGS = $(OPTG) $(DEFINES) $(INCLUDES)
  368. X
  369. XLINTFLAGS = -bhuxz
  370. X
  371. X
  372. X# Software components
  373. X
  374. XHDRS = ether.h
  375. X
  376. XCSRCS = etheraddr.c etherints.c ethere2a.c ethera2e.c etherarp.c etherlocal.c \
  377. X ethere2ip.c etherip2e.c ethere2h.c etherh2e.c etherhe2e.c
  378. XCOBJS = etheraddr.o etherints.o ethere2a.o ethera2e.o etherarp.o etherlocal.o \
  379. X ethere2ip.o etherip2e.o ethere2h.o etherh2e.o etherhe2e.o
  380. X
  381. X# SunOS 4.0
  382. X#SRCS = $(CSRCS) etherblock.c etherread.c etherreadv.c \
  383. X# nitaddr.c nit4self.c nit4intaddr.c nit4open.c nit4write.c nit4writev.c
  384. X#OBJS = $(COBJS) etherblock.o etherread.o etherreadv.o \
  385. X# nitaddr.o nit4self.o nit4intaddr.o nit4open.o nit4write.o nit4writev.o
  386. X
  387. X# SunOS 3.x
  388. X#SRCS = $(CSRCS) etherblock.c nitaddr.c nit3self.c nit3intaddr.c \
  389. X# nit3open.c nit3read.c nit3readv.c nit3write.c nit3writev.c
  390. X#OBJS = $(COBJS) etherblock.o nitaddr.o nit3self.o nit3intaddr.o \
  391. X# nit3open.o nit3read.o nit3readv.o nit3write.o nit3writev.o
  392. X
  393. X# Ultrix
  394. X#SRCS = $(CSRCS) etherblock.c dliaddr.c dliself.c dliintaddr.c \
  395. X# dliopen.c dliread.c dlireadv.c dliwrite.c dliwritev.c
  396. X#OBJS = $(COBJS) etherblock.o dliaddr.o dliself.o dliintaddr.o \
  397. X# dliopen.o dliread.o dlireadv.o dliwrite.o dliwritev.o
  398. X
  399. X# Stanford enetfilter
  400. X#SRCS = $(CSRCS) etherread.c etherreadv.c enetblock.c enetaddr.c \
  401. X# enetintaddr.c enetself.c enetopen.c enetwrite.c enetwritev.c
  402. X#OBJS = $(COBJS) etherread.o etherreadv.o enetblock.o enetaddr.o \
  403. X# enetintaddr.o enetself.o enetopen.o enetwrite.o enetwritev.o
  404. X
  405. X
  406. XLISTS = etheraddr.ps etherints.ps ethere2a.ps ethera2e.ps etherarp.ps \
  407. X etherlocal.ps ethere2ip.ps etherip2e.ps ethere2h.ps etherh2e.ps etherhe2e.ps \
  408. X etherblock.ps etherread.ps etherreadv.ps nitaddr.ps \
  409. X nit4self.ps nit4intaddr.ps nit4open.ps nit4write.ps nit4writev.ps \
  410. X nit3self.ps nit3intaddr.ps nit3open.ps \
  411. X nit3read.ps nit3readv.ps nit3write.ps nit3writev.ps \
  412. X dliaddr.ps dliself.ps dliintaddr.ps dliopen.ps \
  413. X dliread.ps dlireadv.ps dliwrite.ps dliwritev.ps \
  414. X enetblock.ps enetaddr.ps enetself.ps enetintaddr.ps enetopen.ps \
  415. X enetwrite.ps enetwritev.ps
  416. X
  417. X
  418. X# Default dependency - remake all out of date object files
  419. X
  420. Xdefault: all
  421. X
  422. Xall: libether.a
  423. X
  424. Xlibether.a: $(OBJS)
  425. X    ar curv $@ $(OBJS)
  426. X    ranlib $@
  427. X
  428. Xetheraddr.o: etheraddr.c
  429. X    $(CC) $(CFLAGS) -R -c etheraddr.c
  430. X
  431. Xtest: ethertest
  432. X    ./ethertest
  433. X
  434. Xethertest: ethertest.o libether.a
  435. X    $(CC) $(LDFLAGS) -o ethertest ethertest.o libether.a
  436. X
  437. Xethertest.o:
  438. X    $(CC) $(CFLAGS) -c ../tests/ethertest.c
  439. X
  440. Xctp: ctp.o libether.a
  441. X    $(CC) $(LDFLAGS) -o ctp ctp.o libether.a
  442. X
  443. Xctp.o:
  444. X    $(CC) $(CFLAGS) -c ../tests/ctp.c
  445. X
  446. X$(OBJS): $(HDRS)
  447. X
  448. X
  449. X# Fluff test
  450. X
  451. Xlint: $(SRCS) ../tests/ethertest.c
  452. X    -lint $(LINTFLAGS) $(DEFINES) $(INCLUDES) -I. $?
  453. X
  454. X
  455. X# Vgrind formatted listing
  456. X
  457. Xlisting: index $(LISTS) index.ps
  458. X
  459. Xindex.ps: index
  460. X    sort -fu -o index index
  461. X    $(VGRIND) -t -x index > index.ps
  462. X
  463. Xindex: /dev/null
  464. X    ctags -tv $(SRCS) $(HDRS) >> index 2>/dev/null
  465. X
  466. X
  467. X# Utility operations
  468. X
  469. Xclean:
  470. X    rm -f $(OBJS) libether.a ethertest.o ethertest ctp.o ctp
  471. X
  472. Xcleanlists:
  473. X    rm -f $(LISTS) index
  474. X
  475. Xrealclean: clean cleanlists
  476. X
  477. Xinstall: all
  478. X    $(INSTALL) ether.3n $(MANDIR)/man3
  479. X    cd src; $(INSTALL) ether.h $(INCDIR)
  480. X    $(INSTALL) $(SYSTEM)/libether.a $(LIBDIR)/libether.a
  481. X    $(RANLIB) $(LIBDIR)/libether.a
  482. END_OF_FILE
  483. if test 3830 -ne `wc -c <'./src/Makefile'`; then
  484.     echo shar: \"'./src/Makefile'\" unpacked with wrong size!
  485. fi
  486. # end of './src/Makefile'
  487. fi
  488. if test -f './src/dliopen.c' -a "${1}" != "-c" ; then 
  489.   echo shar: Will not clobber existing file \"'./src/dliopen.c'\"
  490. else
  491. echo shar: Extracting \"'./src/dliopen.c'\" \(3045 characters\)
  492. sed "s/^X//" >'./src/dliopen.c' <<'END_OF_FILE'
  493. X/* $Id: dliopen.c,v 2.1 89/10/23 15:42:00 dupuy Exp $ */
  494. X
  495. X#include <sys/param.h>            /* NOFILE */
  496. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  497. X
  498. X#include <net/if.h>            /* ifdevea */
  499. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  500. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  501. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  502. X
  503. X#include <ctype.h>            /* isdigit */
  504. X#include <errno.h>            /* EMFILE */
  505. X
  506. X#include "libether.h"
  507. X
  508. Xether_addr _ether_multi_addrs[NOFILE];
  509. Xstruct sockaddr_dl _ether_sockaddrs[NOFILE];
  510. X
  511. X#define multi_addr (_ether_multi_addrs[fd])
  512. X#define sad (_ether_sockaddrs[fd])
  513. X
  514. X
  515. Xstatic void
  516. Xname_to_devid (devid, name)
  517. Xstruct dli_devid *devid;
  518. Xchar *name;
  519. X{
  520. X    register int i = 0;
  521. X
  522. X    while ((*name != '\0') && (isalpha (name[i]) != 0) && (i < DLI_DEVSIZE))
  523. X    {
  524. X    devid->dli_devname[i] = name[i];
  525. X    i++;
  526. X    }
  527. X
  528. X    devid->dli_devname[i] = '\0';
  529. X
  530. X    devid->dli_devnumber = atoi (&name[i]);
  531. X}
  532. X
  533. X
  534. X/*
  535. X * Returns file descriptor for ethernet device by name ("de0", "qe0", etc.).
  536. X * If name is NULL, uses primary ethernet interface.  Will only receive
  537. X * packets of type specified.  Will receive packets for the ethernet address
  538. X * specified, or local ethernet address if NULL.  If there is an error,
  539. X * returns (-1) and the appropriate value is left in errno.  Normal return
  540. X * status zero. Requires superuser privilege.
  541. X */
  542. X
  543. Xint
  544. Xether_open (name, type, address)
  545. Xchar *name;
  546. Xunsigned type;
  547. Xether_addr *address;
  548. X{
  549. X    int fd;
  550. X    char **interfaces;
  551. X    int saved_errno;            /* close seems to blow errno away */
  552. X
  553. X    if (name == 0)
  554. X    {                    /* get default ethernet interface */
  555. X    interfaces = ether_interfaces ();
  556. X    if (interfaces == 0 || *interfaces == 0)
  557. X        return (-1);
  558. X
  559. X    name = *interfaces;        /* just use the first name in list */
  560. X    }
  561. X
  562. X    if ((fd = socket (AF_DLI, SOCK_DGRAM, DLPROTO_DLI)) < 0)
  563. X    {
  564. X#ifdef DEBUG
  565. X    perror ("ether_open: socket");
  566. X#endif
  567. X    return (-1);
  568. X    }
  569. X
  570. X    if (fd >= NOFILE)            /* not worth making it work here */
  571. X    {
  572. X    (void) close (fd);
  573. X    errno = EMFILE;
  574. X    return (-1);
  575. X    }
  576. X
  577. X    if (type > ETHER_MAXTYPE)
  578. X    {
  579. X    (void) close (fd);
  580. X    errno = EINVAL;
  581. X    return (-1);
  582. X    }
  583. X
  584. X    bzero (&sad, sizeof (sad));
  585. X    sad.dli_family = AF_DLI;
  586. X    sad.dli_substructype = DLI_ETHERNET;
  587. X    name_to_devid (&sad.dli_device, name);
  588. X    sad.choose_addr.dli_eaddr.dli_ioctlflg = DLI_EXCLUSIVE;
  589. X    sad.choose_addr.dli_eaddr.dli_protype = type;
  590. X
  591. X    if (bind (fd, (struct sockaddr *) &sad, sizeof (sad)) != 0)
  592. X    {
  593. X    saved_errno = errno;
  594. X#ifdef DEBUG
  595. X    perror ("ether_open: bind");
  596. X#endif
  597. X    (void) close (fd);
  598. X    errno = saved_errno;
  599. X    return (-1);
  600. X    }
  601. X
  602. X    if (address != 0)            /* a multicast address */
  603. X    {
  604. X    if (setsockopt (fd, DLPROTO_DLI, DLI_MULTICAST, (char *) address,
  605. X            sizeof (ether_addr)) != 0)
  606. X    {
  607. X        saved_errno = errno;
  608. X#ifdef DEBUG
  609. X        perror ("ether_open: setsockopt");
  610. X#endif
  611. X        (void) close (fd);
  612. X        errno = saved_errno;
  613. X        return (-1);
  614. X    }
  615. X    multi_addr = *address;
  616. X    }
  617. X    else
  618. X    multi_addr = ether_bcast_addr;
  619. X
  620. X    sad.choose_addr.dli_eaddr.dli_ioctlflg = 0;
  621. X
  622. X    return (fd);
  623. X}
  624. END_OF_FILE
  625. if test 3045 -ne `wc -c <'./src/dliopen.c'`; then
  626.     echo shar: \"'./src/dliopen.c'\" unpacked with wrong size!
  627. fi
  628. # end of './src/dliopen.c'
  629. fi
  630. if test -f './src/enetopen.c' -a "${1}" != "-c" ; then 
  631.   echo shar: Will not clobber existing file \"'./src/enetopen.c'\"
  632. else
  633. echo shar: Extracting \"'./src/enetopen.c'\" \(5128 characters\)
  634. sed "s/^X//" >'./src/enetopen.c' <<'END_OF_FILE'
  635. X/* $Id: enetopen.c,v 2.1 89/10/23 15:42:14 dupuy Exp $ */
  636. X
  637. X#include <strings.h>            /* strncpy */
  638. X
  639. X#include <sys/file.h>            /* O_RDWR */
  640. X#include <sys/types.h>            /* enfilter (u_char) */
  641. X#include <sys/socket.h>            /* IFNAMSIZ (sockaddr) */
  642. X#include <sys/ioctl.h>            /* ioctl */
  643. X
  644. X#include <net/if.h>            /* IFNAMSIZ */
  645. X#include <net/enet.h>            /* enfilter */
  646. X
  647. X#include <netinet/in.h>            /* htons */
  648. X
  649. X#include <errno.h>            /* EMFILE/EINVAL */
  650. X
  651. Xextern int errno;
  652. X
  653. X#include "libether.h"
  654. X
  655. X#ifndef ENET_DEVDIR
  656. X#define ENET_DEVDIR "/dev/enet/"
  657. X#endif
  658. X
  659. X#define packetfilt    enfilter
  660. X#define Pf_Priority    enf_Priority
  661. X#define Pf_FilterLen    enf_FilterLen
  662. X#define Pf_Filter    enf_Filter
  663. X
  664. X
  665. Xstatic ether_addr promiscuous;
  666. X
  667. Xunsigned _ether_types[FD_SETSIZE];
  668. X
  669. X#define ether_type (_ether_types[fd])
  670. X
  671. X#ifdef __STDC__
  672. Xvoid _ether_newaddr (int fd);
  673. X#else
  674. Xvoid _ether_newaddr ();
  675. X#endif
  676. X
  677. X
  678. Xstatic int
  679. Xeiocsetf (fd, filter)
  680. Xint fd;
  681. Xstruct packetfilt *filter;
  682. X{
  683. X    int saved_errno;
  684. X    filter->Pf_Priority = 1;        /* should be < 2 */
  685. X
  686. X    if (ioctl (fd, EIOCSETF, (char *) filter) < 0)
  687. X    {
  688. X    saved_errno = errno;
  689. X    (void) close (fd);
  690. X    errno = saved_errno;
  691. X    return (-1);
  692. X    }
  693. X
  694. X    return (0);
  695. X}
  696. X
  697. X/*
  698. X * Returns file descriptor for ethernet device by name ("ie0", "le0", etc.).
  699. X * If name is NULL, uses primary ethernet interface.  Will only receive
  700. X * packets of type specified.  Will receive packets for the ethernet address
  701. X * specified, or local ethernet address if NULL.  If there is an error,
  702. X * returns (-1) and the appropriate value is left in errno.  Normal return
  703. X * status zero. Requires superuser privilege.
  704. X */
  705. X
  706. Xint
  707. Xether_open (name, type, address)
  708. Xchar *name;
  709. Xunsigned type;
  710. Xether_addr *address;
  711. X{
  712. X    int fd;
  713. X    struct packetfilt filter;
  714. X    unsigned short *fptr = 0;
  715. X    char **interfaces;
  716. X    char pathname[sizeof (ENET_DEVDIR) + IFNAMSIZ];
  717. X#if !defined(MULTICAST) && defined(PROMISCUOUS)
  718. X    register int i;
  719. X#endif
  720. X
  721. X    if (name == 0)            /* get default ethernet interface */
  722. X    {
  723. X    interfaces = ether_interfaces ();
  724. X    if (interfaces == 0 || *interfaces == 0)
  725. X        return (-1);
  726. X
  727. X    name = *interfaces;        /* just use the first name in list */
  728. X    }
  729. X
  730. X    (void) strcpy (pathname, ENET_DEVDIR);
  731. X    (void) strncat (pathname, name, IFNAMSIZ);
  732. X
  733. X    if ((fd = open (pathname, O_RDWR)) < 0)
  734. X    {
  735. X#ifdef DEBUG
  736. X    perror (pathname);
  737. X#endif
  738. X    return (-1);
  739. X    }
  740. X
  741. X    if (fd >= FD_SETSIZE)        /* not worth making it work here */
  742. X    {
  743. X    (void) close (fd);
  744. X    errno = EMFILE;
  745. X    return (-1);
  746. X    }
  747. X
  748. X    /* set up filter */
  749. X
  750. X    if (type != ETHER_ALLTYPES)        /* hack for NIT features */
  751. X    {
  752. X    if (type > ETHER_MAXTYPE)
  753. X    {
  754. X        (void) close (fd);
  755. X        errno = EINVAL;
  756. X        return (-1);
  757. X    }
  758. X
  759. X
  760. X    fptr = &filter.Pf_Filter[0];
  761. X
  762. X    *fptr++ = ENF_PUSHWORD + ETHER_TYPE / sizeof (short);
  763. X    *fptr++ = ENF_PUSHLIT | ENF_EQ;
  764. X    *fptr++ = htons ((u_short) type);
  765. X
  766. X    filter.Pf_FilterLen = fptr - &filter.Pf_Filter[0];
  767. X
  768. X    if (eiocsetf (fd, &filter) < 0)
  769. X        return (-1);
  770. X    }
  771. X
  772. X    if (address != 0)
  773. X    {
  774. X    if (ether_cmp (address, &promiscuous))
  775. X    {
  776. X#if !defined(MULTICAST) && defined(PROMISCUOUS)
  777. X        ether_addr local_addr;
  778. X#endif
  779. X        if (!ETHER_MCAST (address))
  780. X        {
  781. X#ifdef DEBUG
  782. X        (void) printf ("rejecting non-multicast address argument\n");
  783. X#endif
  784. X        (void) close (fd);
  785. X        errno = EINVAL;
  786. X        return (-1);
  787. X        }
  788. X
  789. X#ifdef MULTICAST
  790. X        /* #error not clear how to set multicast addresses */
  791. X        exit (-1);            /* die die die */
  792. X#else
  793. X#ifdef PROMISCUOUS
  794. X
  795. X        /*
  796. X         * Enable address matching filter before we go into promiscuous
  797. X         * mode.
  798. X         */
  799. X
  800. X        (void) ether_address (fd, &local_addr);
  801. X
  802. X        fptr = &filter.Pf_Filter[0];
  803. X
  804. X        if (type != ETHER_ALLTYPES)    /* hack for NIT features */
  805. X        {
  806. X        *fptr++ = ENF_PUSHWORD + ETHER_TYPE / sizeof (short);
  807. X        *fptr++ = ENF_PUSHLIT;
  808. X        *fptr++ = htons (type);    /* should be in host order */
  809. X        *fptr++ = ENF_CAND;
  810. X        }
  811. X
  812. X        for (i = 0; i < 3; i++)    /* compare addresses in 3 shorts */
  813. X        {
  814. X        *fptr++ = ENF_PUSHWORD + ETHER_DST / sizeof (short) + i;
  815. X        *fptr++ = ENF_PUSHLIT | ENF_EQ;
  816. X        *fptr++ = ((short *) address)[i];
  817. X        *fptr++ = ENF_PUSHWORD + ETHER_DST / sizeof (short) + i;
  818. X        *fptr++ = ENF_PUSHLIT | ENF_EQ;
  819. X        *fptr++ = ((short *) ðer_bcast_addr)[i];
  820. X        *fptr++ = ENF_OR;
  821. X        *fptr++ = ENF_PUSHWORD + ETHER_DST / sizeof (short) + i;
  822. X        *fptr++ = ENF_PUSHLIT | ENF_EQ;
  823. X        *fptr++ = ((short *) &local_addr)[i];
  824. X        *fptr++ = ENF_CNOR;
  825. X        }
  826. X
  827. X        filter.Pf_FilterLen = fptr - &filter.Pf_Filter[0];
  828. X
  829. X        if (eiocsetf (fd, &filter) < 0)
  830. X        return (-1);
  831. X#else
  832. X#ifdef DEBUG
  833. X        (void) printf ("rejecting multicast address argument\n");
  834. X#endif
  835. X        (void) close (fd);
  836. X        errno = EINVAL;
  837. X        return (-1);
  838. X
  839. X#endif                    /* PROMISCUOUS */
  840. X
  841. X#endif                    /* MULTICAST */
  842. X
  843. X    }
  844. X
  845. X#ifdef MULTICAST
  846. X    else                /* only promiscuous if requested */
  847. X# endif
  848. X    {                /* go into promiscuous mode */
  849. X
  850. X#ifdef PROMISCUOUS
  851. X        /* #error not clear how to set promiscuous mode */
  852. X        exit (-1);            /* die die die */
  853. X#else
  854. X#ifdef DEBUG
  855. X        (void) printf ("rejecting promiscuous address argument\n");
  856. X#endif
  857. X        (void) close (fd);
  858. X        errno = EINVAL;
  859. X        return (-1);
  860. X
  861. X#endif                    /* PROMISCUOUS */
  862. X
  863. X    }
  864. X    }
  865. X
  866. X    _ether_newaddr (fd);
  867. X    ether_type = type;
  868. X    return (fd);
  869. X}
  870. END_OF_FILE
  871. if test 5128 -ne `wc -c <'./src/enetopen.c'`; then
  872.     echo shar: \"'./src/enetopen.c'\" unpacked with wrong size!
  873. fi
  874. # end of './src/enetopen.c'
  875. fi
  876. if test -f './src/ether.h' -a "${1}" != "-c" ; then 
  877.   echo shar: Will not clobber existing file \"'./src/ether.h'\"
  878. else
  879. echo shar: Extracting \"'./src/ether.h'\" \(3510 characters\)
  880. sed "s/^X//" >'./src/ether.h' <<'END_OF_FILE'
  881. X/* $Id: ether.h,v 2.2 89/10/23 15:42:19 dupuy Exp $ */
  882. X
  883. X/* Interface definitions for ethernet access library */
  884. X
  885. Xtypedef union etheraddr
  886. X{
  887. X    unsigned char bytes[6];        /* byteorder safe initialization */
  888. X    unsigned short shorts[3];        /* force 2-byte alignment */
  889. X}
  890. X      ether_addr;
  891. X
  892. Xtypedef struct etherpacket
  893. X{
  894. X    ether_addr dest;
  895. X    ether_addr src;
  896. X    unsigned char type[2];        /* in network byte order! */
  897. X    unsigned short pktlen;        /* length of pktbuf ONLY */
  898. X    char *pktbuf;
  899. X}
  900. X        ether_packet;
  901. X
  902. Xtypedef struct ethervec
  903. X{
  904. X    ether_addr dest;
  905. X    ether_addr src;
  906. X    unsigned char type[2];        /* in network byte order! */
  907. X    unsigned short iovcnt;        /* number of iovec to use */
  908. X    struct iovec *iov;            /* ptr to array of iovec */
  909. X}
  910. X     ether_vec;
  911. X
  912. X#ifndef __ETHER_BCAST_ADDR__
  913. Xextern ether_addr ether_bcast_addr;
  914. X#endif
  915. X
  916. X#ifdef __STDC__
  917. X
  918. Xint ether_open (char *name, unsigned type, ether_addr * address);
  919. X
  920. Xether_addr *ether_address (int fd, ether_addr * address);
  921. X
  922. Xether_addr *ether_intfaddr (char *intf, ether_addr * address);
  923. X
  924. Xchar **ether_interfaces (void);
  925. X
  926. Xint ether_write (int fd, ether_packet * packet);
  927. X
  928. Xint ether_writev (int fd, ether_vec * packet);
  929. X
  930. Xint ether_read (int fd, ether_packet * packet);
  931. X
  932. Xint ether_readv (int fd, ether_vec * packet);
  933. X
  934. Xint ether_blocking (int fd, int state);
  935. X
  936. Xint ether_send_self (int fd);
  937. X
  938. Xint ether_mcast_self (int fd);
  939. X
  940. Xint ether_bcast_self (int fd);
  941. X
  942. Xchar *ether_ntoa (ether_addr *);
  943. X
  944. Xether_addr *ether_aton (char *);
  945. X
  946. X#ifdef __GNUC__
  947. X
  948. X/*
  949. X * Avoid stupid warnings if structs aren't defined
  950. X */
  951. X
  952. Xtypedef struct in_addr *_ether_NoNsEnSe;
  953. Xtypedef struct hostent *_ether_nOnSeNsE;
  954. X
  955. X#endif
  956. X
  957. Xchar *ether_e2a (ether_addr *, char *);
  958. X
  959. Xether_addr *ether_a2e (char *, ether_addr *);
  960. X
  961. Xstruct in_addr *ether_e2ip (ether_addr *, struct in_addr *);
  962. X
  963. Xether_addr *ether_ip2e (struct in_addr *, ether_addr *);
  964. X
  965. Xchar *ether_e2host (ether_addr *, char *);
  966. X
  967. Xether_addr *ether_host2e (char *, ether_addr *);
  968. X
  969. Xether_addr *ether_hostent2e (struct hostent *, ether_addr *);
  970. X
  971. X#else
  972. X
  973. Xint ether_open ();
  974. Xether_addr *ether_address ();
  975. Xether_addr *ether_intfaddr ();
  976. Xchar **ether_interfaces ();
  977. Xint ether_write ();
  978. Xint ether_writev ();
  979. Xint ether_read ();
  980. Xint ether_readv ();
  981. Xint ether_blocking ();
  982. Xint ether_send_self ();
  983. Xint ether_mcast_self ();
  984. Xint ether_bcast_self ();
  985. X
  986. Xchar *ether_ntoa ();
  987. Xether_addr *ether_aton ();
  988. Xchar *ether_e2a ();
  989. Xether_addr *ether_a2e ();
  990. Xstruct in_addr *ether_e2ip ();
  991. Xether_addr *ether_ip2e ();
  992. Xchar *ether_e2host ();
  993. Xether_addr *ether_host2e ();
  994. Xether_addr *ether_hostent2e ();
  995. X
  996. X#endif
  997. X
  998. X#undef ether_cmp            /* lose def from netinet/if_ether.h */
  999. X
  1000. X#define ether_cmp(addr1,addr2) \
  1001. X ((addr1)->shorts[0] != (addr2)->shorts[0] \
  1002. X  || (addr1)->shorts[1] != (addr2)->shorts[1] \
  1003. X  || (addr1)->shorts[2] != (addr2)->shorts[2])
  1004. X
  1005. X#define ETHERSTRLEN 18            /* max length of "xx:xx:xx:xx:xx:xx" */
  1006. X
  1007. X#ifdef NOFILE                /* i.e. we have included sys/param.h */
  1008. X#ifndef MAXHOSTNAMELEN            /* but MAXHOSTNAMELEN still isnt set */
  1009. X#define MAXHOSTNAMELEN 64
  1010. X#endif
  1011. X#endif
  1012. X
  1013. X/* should be defined in terms of ether_packet struct; need offsetof() macro */
  1014. X
  1015. X#define ETHER_DST    0
  1016. X#define ETHER_SRC    6
  1017. X#define ETHER_TYPE    12
  1018. X#define ETHER_PKT    14
  1019. X#define ETHER_MIN    46
  1020. X#define ETHER_MAX    1500
  1021. X
  1022. X#define ETHER_MINTYPE    0x5DD        /* lowest protocol not valid IEEE802 */
  1023. X#define ETHER_MAXTYPE    0xFFFF        /* largest possible protocol */
  1024. X
  1025. X#define ETHER_MCAST(addr) (((unsigned char *) (addr))[0] & 0x01)
  1026. X
  1027. X#ifdef NT_ALLTYPES
  1028. X#define ETHER_ALLTYPES NT_ALLTYPES
  1029. X#else
  1030. X#define ETHER_ALLTYPES ((unsigned) -1)
  1031. X#endif
  1032. END_OF_FILE
  1033. if test 3510 -ne `wc -c <'./src/ether.h'`; then
  1034.     echo shar: \"'./src/ether.h'\" unpacked with wrong size!
  1035. fi
  1036. # end of './src/ether.h'
  1037. fi
  1038. if test -f './src/etherarp.c' -a "${1}" != "-c" ; then 
  1039.   echo shar: Will not clobber existing file \"'./src/etherarp.c'\"
  1040. else
  1041. echo shar: Extracting \"'./src/etherarp.c'\" \(4253 characters\)
  1042. sed "s/^X//" >'./src/etherarp.c' <<'END_OF_FILE'
  1043. X/* $Id: etherarp.c,v 2.1 89/10/23 15:42:24 dupuy Exp $ */
  1044. X
  1045. X#include <sys/types.h>            /* arptab (u_short) */
  1046. X#include <sys/socket.h>            /* arptab (sockaddr) */
  1047. X#include <net/if.h>            /* arptab (ifnet) */
  1048. X#ifdef _SOCKET_                /* 4.0 system? */
  1049. X#include <net/if_arp.h>            /* arptab (arphdr) */
  1050. X#endif
  1051. X#include <netinet/in.h>            /* in_addr */
  1052. X#include <netinet/if_ether.h>        /* arptab */
  1053. X
  1054. X#include <sys/file.h>            /* O_RDONLY */
  1055. X#include <nlist.h>            /* nlist */
  1056. X
  1057. X#include "libether.h"
  1058. X
  1059. X/*
  1060. X * This only understands IP ARP entries.  Chaos, Appletalk, etc. are unknown.
  1061. X * Standard kernels don't keep arp tables for those protocols anyhow.
  1062. X */
  1063. X
  1064. Xstruct nlist nl[] = {
  1065. X#define    X_ARPTAB    0
  1066. X    {"_arptab"},
  1067. X#define    X_ARPTAB_SIZE    1
  1068. X    {"_arptab_size"},
  1069. X    {""},
  1070. X};
  1071. X
  1072. X#ifndef KERNEL_FILENAME
  1073. X#define KERNEL_FILENAME "/vmunix"
  1074. X#endif
  1075. X
  1076. X#ifndef KMEM_FILENAME
  1077. X#define KMEM_FILENAME "/dev/kmem"
  1078. X#endif
  1079. X
  1080. Xstatic int
  1081. Xkmem_read (fd, addr, buf, nbytes)
  1082. Xint fd;
  1083. Xunsigned long addr;
  1084. Xchar *buf;
  1085. Xunsigned nbytes;
  1086. X{
  1087. X    extern long lseek ();
  1088. X
  1089. X    return (lseek (fd, (long) addr, L_SET) == -1L
  1090. X        || read (fd, buf, (int) nbytes) < nbytes);
  1091. X}
  1092. X
  1093. Xstatic int
  1094. Xreadarptable (atp)
  1095. Xstruct arptab **atp;
  1096. X{
  1097. X    int kmem;
  1098. X    int arptab_size;
  1099. X    int bytes;
  1100. X    struct arptab *at;
  1101. X
  1102. X    if (atp == 0)
  1103. X    return (-1);
  1104. X
  1105. X    if ((kmem = open (KMEM_FILENAME, O_RDONLY)) < 0)
  1106. X    return (-1);
  1107. X
  1108. X    /*
  1109. X     * Despite what Ultrix lint says, nlist _does_ return a value
  1110. X     */
  1111. X
  1112. X    if (nlist (KERNEL_FILENAME, nl) != 0)
  1113. X    return (-1);
  1114. X
  1115. X#if defined (sun386) || defined (COFF)
  1116. X    if (nl[X_ARPTAB_SIZE].n_value == 0)
  1117. X#else
  1118. X    if (nl[X_ARPTAB_SIZE].n_type == 0)
  1119. X#endif
  1120. X    return (-1);
  1121. X
  1122. X    if (kmem_read (kmem, nl[X_ARPTAB_SIZE].n_value,
  1123. X           (char *) &arptab_size, (unsigned) sizeof (arptab_size)))
  1124. X    return (-1);
  1125. X
  1126. X    if (arptab_size <= 0 || arptab_size > 10000)
  1127. X    return (-1);
  1128. X
  1129. X    bytes = arptab_size * sizeof (struct arptab);
  1130. X
  1131. X    if (*atp == 0)
  1132. X    *atp = at = (struct arptab *) malloc ((unsigned) bytes);
  1133. X    else
  1134. X    at = *atp;
  1135. X
  1136. X    if (at == 0)
  1137. X    return (0);            /* may be able to get memory later */
  1138. X
  1139. X    if (kmem_read (kmem, nl[X_ARPTAB].n_value, (char *) at, (unsigned) bytes))
  1140. X    return (-1);
  1141. X
  1142. X    (void) close (kmem);
  1143. X
  1144. X    return (arptab_size);
  1145. X}
  1146. X
  1147. X/*
  1148. X * This code is derived from "src/etc/arp.c"
  1149. X *
  1150. X * Copyright (c) 1984 Regents of the University of California. All rights
  1151. X * reserved.
  1152. X *
  1153. X * This code is derived from software contributed to Berkeley by Sun
  1154. X * Microsystems, Inc.
  1155. X *
  1156. X * Redistribution and use in source and binary forms are permitted provided
  1157. X * that the above copyright notice and this paragraph are duplicated in all
  1158. X * such forms and that any documentation, advertising materials, and other
  1159. X * materials related to such distribution and use acknowledge that the software
  1160. X * was developed by the University of California, Berkeley.  The name of the
  1161. X * University may not be used to endorse or promote products derived from this
  1162. X * software without specific prior written permission. THIS SOFTWARE IS
  1163. X * PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
  1164. X * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS
  1165. X * FOR A PARTICULAR PURPOSE.
  1166. X */
  1167. X
  1168. Xint
  1169. X_ether_arpscan (addr, ipaddr)
  1170. Xether_addr *addr;
  1171. Xstruct in_addr *ipaddr;
  1172. X{
  1173. X    static int arptab_size = 0;        /* kernel arptab is fixed size */
  1174. X    static struct arptab *arptab;
  1175. X    struct arptab *at;
  1176. X    int i;
  1177. X    int again = 0;
  1178. X
  1179. X    if (arptab_size == 0)
  1180. X    arptab_size = again = readarptable (&arptab);
  1181. X
  1182. X    if (arptab_size <= 0)
  1183. X    return (0);            /* no luck reading arptab */
  1184. X
  1185. X    while (1)
  1186. X    {
  1187. X    for (i = arptab_size, at = arptab; i-- > 0; at++)
  1188. X    {
  1189. X        if (at->at_iaddr.s_addr == 0 || at->at_flags == 0)
  1190. X        continue;
  1191. X
  1192. X        if ((at->at_flags & ATF_COM) == 0)
  1193. X        continue;
  1194. X
  1195. X#ifdef sun                /* sun defines at_enaddr as struct */
  1196. X        if (!bcmp ((char *) &at->at_enaddr, (char *) addr, sizeof (*addr)))
  1197. X#else
  1198. X        if (bcmp ((char *) at->at_enaddr, (char *) addr, sizeof (*addr))
  1199. X        == 0)
  1200. X#endif
  1201. X        {
  1202. X        *ipaddr = at->at_iaddr;
  1203. X        return (1);
  1204. X        }
  1205. X    }
  1206. X
  1207. X    if (again)
  1208. X        return (0);
  1209. X    else                /* try again with current table */
  1210. X        again = readarptable (&arptab);
  1211. X    }
  1212. X
  1213. X    /* NOTREACHED */
  1214. X}
  1215. X
  1216. X#ifdef RARP
  1217. X
  1218. Xint
  1219. X_ether_rarpprobe (addr, ipaddr)
  1220. Xether_addr *addr;
  1221. Xstruct in_addr *ipaddr;
  1222. X{
  1223. X    return (0);
  1224. X}
  1225. X
  1226. X#endif
  1227. END_OF_FILE
  1228. if test 4253 -ne `wc -c <'./src/etherarp.c'`; then
  1229.     echo shar: \"'./src/etherarp.c'\" unpacked with wrong size!
  1230. fi
  1231. # end of './src/etherarp.c'
  1232. fi
  1233. if test -f './src/ethere2h.c' -a "${1}" != "-c" ; then 
  1234.   echo shar: Will not clobber existing file \"'./src/ethere2h.c'\"
  1235. else
  1236. echo shar: Extracting \"'./src/ethere2h.c'\" \(2461 characters\)
  1237. sed "s/^X//" >'./src/ethere2h.c' <<'END_OF_FILE'
  1238. X/* $Id: ethere2h.c,v 2.1 89/10/23 15:42:30 dupuy Exp $ */
  1239. X
  1240. X#include <sys/param.h>            /* MAXHOSTNAMELEN */
  1241. X#include <sys/socket.h>            /* AF_INET */
  1242. X#include <netinet/in.h>            /* in_addr */
  1243. X
  1244. X#include <netdb.h>            /* hostent */
  1245. X#include <strings.h>            /* strncpy */
  1246. X
  1247. X#include "libether.h"
  1248. X
  1249. Xstatic char *
  1250. Xip2host (addr, hname)
  1251. Xstruct in_addr *addr;
  1252. Xchar *hname;
  1253. X{
  1254. X#ifdef lint
  1255. X    char *sprintf ();
  1256. X#endif
  1257. X    struct hostent *host;
  1258. X
  1259. X    /*
  1260. X     * Unfortunately, gethostbyaddr is not reentrant.  It should be.
  1261. X     */
  1262. X
  1263. X    if (host = gethostbyaddr ((char *) addr, sizeof (struct in_addr), AF_INET))
  1264. X    (void) strncpy (hname, host->h_name, MAXHOSTNAMELEN);
  1265. X    else                /* use dotted-quad notation */
  1266. X    (void) sprintf (hname, "[%d.%d.%d.%d]",
  1267. X            (addr->s_addr >> 24) & 0xff,
  1268. X            (addr->s_addr >> 16) & 0xff,
  1269. X            (addr->s_addr >> 8) & 0xff,
  1270. X            addr->s_addr & 0xff);
  1271. X
  1272. X    return (hname);
  1273. X}
  1274. X
  1275. Xchar *
  1276. Xether_e2host (addr, hname)
  1277. Xether_addr *addr;
  1278. Xchar *hname;
  1279. X{
  1280. X    struct in_addr ipaddr;
  1281. X    int allocated = 0;
  1282. X
  1283. X    if (hname == NULL)
  1284. X    {
  1285. X    hname = (char *) malloc (MAXHOSTNAMELEN);
  1286. X    allocated++;
  1287. X    }
  1288. X
  1289. X    if (hname == NULL)
  1290. X    return (NULL);
  1291. X
  1292. X#ifdef ETHERDB
  1293. X    if (ether_ntohost (hname, addr) == 0)
  1294. X    return (hname);
  1295. X#endif
  1296. X
  1297. X    /*
  1298. X     * At this point we would like to ioctl the arp table and see if we
  1299. X     * already have an entry for this ethernet address.     But the arp table is
  1300. X     * hashed by protocol address, not by ethernet address, so we have to
  1301. X     * grovel though /dev/kmem and look at all the entries.  And after that,
  1302. X     * we may not find an entry for the ethernet address anyhow.
  1303. X     */
  1304. X
  1305. X    if (_ether_arpscan (addr, &ipaddr))
  1306. X    return (ip2host (&ipaddr, hname));
  1307. X
  1308. X    /*
  1309. X     * Since the kernel doesn't keep an entry for the local interfaces in the
  1310. X     * arp table, we also check the ethernet addresses for each of those
  1311. X     * looking for a match.
  1312. X     */
  1313. X
  1314. X    if (_ether_localif (addr, &ipaddr))
  1315. X    return (ip2host (&ipaddr, hname));
  1316. X
  1317. X#ifdef RARP
  1318. X
  1319. X    /*
  1320. X     * Now the only alternative left is to use RARP (via ether_open, etc.) to
  1321. X     * try to get the IP address.  Unfortunately, most machines won't RARP for
  1322. X     * themselves, so this isn't terribly useful either.  Especially since we
  1323. X     * probably need superuser privilege to call ether_open!
  1324. X     */
  1325. X
  1326. X    if (_ether_rarpprobe (addr, &ipaddr))
  1327. X    return (ip2host (&ipaddr, hname));
  1328. X#endif
  1329. X
  1330. X    if (allocated)            /* sigh, dispose it */
  1331. X    (void) free (hname);
  1332. X
  1333. X    return (NULL);            /* too bad, we failed */
  1334. X}
  1335. END_OF_FILE
  1336. if test 2461 -ne `wc -c <'./src/ethere2h.c'`; then
  1337.     echo shar: \"'./src/ethere2h.c'\" unpacked with wrong size!
  1338. fi
  1339. # end of './src/ethere2h.c'
  1340. fi
  1341. if test -f './src/ethere2ip.c' -a "${1}" != "-c" ; then 
  1342.   echo shar: Will not clobber existing file \"'./src/ethere2ip.c'\"
  1343. else
  1344. echo shar: Extracting \"'./src/ethere2ip.c'\" \(3364 characters\)
  1345. sed "s/^X//" >'./src/ethere2ip.c' <<'END_OF_FILE'
  1346. X/* $Id: ethere2ip.c,v 2.1 89/10/23 15:42:32 dupuy Exp $ */
  1347. X
  1348. X#include <sys/param.h>            /* MAXHOSTNAMELEN */
  1349. X#include <sys/socket.h>            /* AF_INET */
  1350. X#include <netinet/in.h>            /* in_addr */
  1351. X
  1352. X#include <netdb.h>            /* hostent */
  1353. X
  1354. X#include "libether.h"
  1355. X
  1356. Xstruct in_addr *
  1357. Xether_e2ip (addr, ipaddr)
  1358. Xether_addr *addr;
  1359. Xstruct in_addr *ipaddr;
  1360. X{
  1361. X#ifdef ETHERDB
  1362. X    char hname[MAXHOSTNAMELEN];
  1363. X    struct hostent *host;
  1364. X#endif
  1365. X    int allocated = 0;
  1366. X
  1367. X    if (ipaddr == NULL)
  1368. X    {
  1369. X    ipaddr = (struct in_addr *) malloc (sizeof (struct in_addr));
  1370. X    allocated++;
  1371. X    }
  1372. X
  1373. X    if (ipaddr == NULL)
  1374. X    return (NULL);
  1375. X
  1376. X#ifdef ETHERDB
  1377. X    if (ether_ntohost (hname, addr) == 0)
  1378. X    {
  1379. X
  1380. X    /*
  1381. X     * Unfortunately, gethostbyname is not reentrant.  It should be.
  1382. X     */
  1383. X
  1384. X    if ((host = gethostbyname (hname)) && host->h_addrtype == AF_INET)
  1385. X    {
  1386. X        ether_addr arpaddr;
  1387. X        struct in_addr haddr;
  1388. X        int arpsucceeded = 0;
  1389. X
  1390. X        /*
  1391. X         * We have the answer(s), but they may be wrong.  Check with ARP.
  1392. X         */
  1393. X
  1394. X#ifdef h_addr                /* we have a list */
  1395. X        char **hlist;
  1396. X
  1397. X        for (hlist = host->h_addr_list; *hlist != NULL; hlist++)
  1398. X        {
  1399. X        bcopy (*hlist, (char *) &haddr, sizeof (haddr));
  1400. X#else
  1401. X        bcopy (host->h_addr, (char *) &haddr, sizeof (haddr));
  1402. X#endif
  1403. X        if (ether_ip2e (&haddr, &arpaddr))
  1404. X        {
  1405. X            if (ether_cmp (&arpaddr, addr) == 0)
  1406. X            {
  1407. X            *ipaddr = haddr;
  1408. X            return (ipaddr);
  1409. X            }
  1410. X#ifdef DEBUG                /* warn that etherdb is incorrect */
  1411. X            else
  1412. X            {
  1413. X            char ethera[ETHERSTRLEN];
  1414. X            char etherb[ETHERSTRLEN];
  1415. X            
  1416. X            (void) printf ("bad ether address for %s: %s/%s\n",
  1417. X                       host->h_name,
  1418. X                       ether_e2a (addr, ethera),
  1419. X                       ether_e2a (&arpaddr, etherb));
  1420. X            }
  1421. X#endif
  1422. X            arpsucceeded++;
  1423. X        }
  1424. X#ifdef h_addr
  1425. X        }
  1426. X#endif
  1427. X        if (!arpsucceeded)
  1428. X        {
  1429. X
  1430. X        /*
  1431. X         * We couldn't ARP the address(es).  So we'll use the primary.
  1432. X         */
  1433. X        bcopy (host->h_addr, (char *) ipaddr, sizeof (*ipaddr));
  1434. X        return (ipaddr);
  1435. X        }
  1436. X    }
  1437. X    }
  1438. X#endif
  1439. X
  1440. X    /*
  1441. X     * While the ethers db may be wrong, proxy ARP makes using the ARP table
  1442. X     * even more prone to error.  If RARP were better supported by more
  1443. X     * machines, we would do well to use it before this.
  1444. X     */
  1445. X
  1446. X    /*
  1447. X     * At this point we would like to ioctl the arp table and see if we
  1448. X     * already have an entry for this ethernet address.     But the arp table is
  1449. X     * hashed by protocol address, not by ethernet address, so we have to
  1450. X     * grovel though /dev/kmem and look at all the entries.  And after that,
  1451. X     * we may not find an entry for the ethernet address anyhow.
  1452. X     */
  1453. X
  1454. X    if (_ether_arpscan (addr, ipaddr))
  1455. X    return (ipaddr);
  1456. X
  1457. X    /*
  1458. X     * Since the kernel doesn't keep an entry for the local interfaces in the
  1459. X     * arp table, we also check the ethernet addresses for each of those
  1460. X     * looking for a match.
  1461. X     */
  1462. X
  1463. X    if (_ether_localif (addr, ipaddr))
  1464. X    return (ipaddr);
  1465. X
  1466. X#ifdef RARP
  1467. X
  1468. X    /*
  1469. X     * Now the only alternative left is to use RARP (via ether_open, etc.) to
  1470. X     * try to get the IP address.  Unfortunately, most machines won't RARP for
  1471. X     * themselves, so this isn't terribly useful either.  Especially since we
  1472. X     * probably need superuser privilege to call ether_open!
  1473. X     */
  1474. X
  1475. X    if (_ether_rarpprobe (addr, ipaddr))
  1476. X    return (ipaddr);
  1477. X#endif
  1478. X
  1479. X    if (allocated)            /* sigh, dispose it */
  1480. X    (void) free ((char *) ipaddr);
  1481. X
  1482. X    return (NULL);            /* too bad, we failed */
  1483. X}
  1484. END_OF_FILE
  1485. if test 3364 -ne `wc -c <'./src/ethere2ip.c'`; then
  1486.     echo shar: \"'./src/ethere2ip.c'\" unpacked with wrong size!
  1487. fi
  1488. # end of './src/ethere2ip.c'
  1489. fi
  1490. if test -f './src/etherh2e.c' -a "${1}" != "-c" ; then 
  1491.   echo shar: Will not clobber existing file \"'./src/etherh2e.c'\"
  1492. else
  1493. echo shar: Extracting \"'./src/etherh2e.c'\" \(1936 characters\)
  1494. sed "s/^X//" >'./src/etherh2e.c' <<'END_OF_FILE'
  1495. X/* $Id: etherh2e.c,v 2.1 89/10/24 17:53:15 dupuy Exp $ */
  1496. X
  1497. X#include <sys/types.h>            /* in_addr (u_short) */
  1498. X#include <netinet/in.h>            /* in_addr */
  1499. X
  1500. X#include <netdb.h>            /* hostent */
  1501. X#include <errno.h>            /* ENOENT */
  1502. X
  1503. Xextern int errno;
  1504. X
  1505. X#include "libether.h"
  1506. X
  1507. X/*
  1508. X * derived from ethertools/htoea.c
  1509. X *
  1510. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  1511. X * All Rights Reserved
  1512. X *
  1513. X * Permission is granted to any individual or institution to use, copy, or
  1514. X * redistribute this software so long as it is not sold for profit, provided
  1515. X * that this notice and the original copyright notices are retained.  Boston
  1516. X * University makes no representations about the suitability of this software
  1517. X * for any purpose.  It is provided "as is" without express or implied
  1518. X * warranty.
  1519. X */
  1520. X
  1521. Xether_addr *
  1522. Xether_host2e (hname, addr)
  1523. Xchar *hname;
  1524. Xether_addr *addr;
  1525. X{
  1526. X    int allocated = 0;
  1527. X    struct in_addr ipaddr;
  1528. X    struct hostent *host;
  1529. X    unsigned long inet_addr ();
  1530. X
  1531. X    if (addr == 0)
  1532. X    {
  1533. X    addr = (ether_addr *) malloc (sizeof (ether_addr));
  1534. X    allocated++;
  1535. X    }
  1536. X
  1537. X    if (addr == 0)
  1538. X    return (0);
  1539. X
  1540. X    if (ether_a2e (hname, addr))    /* try ascii ethernet address first */
  1541. X    return (addr);
  1542. X
  1543. X    if ((ipaddr.s_addr = inet_addr (hname)) != (unsigned) -1)
  1544. X    {
  1545. X    if (ether_ip2e (&ipaddr, addr))
  1546. X        return (addr);        /* dotted quad notation ok too */
  1547. X    }
  1548. X
  1549. X#ifdef ETHERDB
  1550. X
  1551. X    /*
  1552. X     * This answer may be wrong, but since the ethers DB may contain non-IP or
  1553. X     * MAC-level devices, it's hard to really check.
  1554. X     */
  1555. X    if (ether_hostton (hname, addr) == 0)
  1556. X    return (addr);
  1557. X#endif ETHERDB
  1558. X
  1559. X    /*
  1560. X     * Unfortunately, gethostbyname is not reentrant.  It should be.
  1561. X     */
  1562. X
  1563. X    if ((host = gethostbyname (hname)) != 0)
  1564. X    {
  1565. X    if (ether_hostent2e (host, addr))
  1566. X        return (addr);
  1567. X    }
  1568. X    else
  1569. X    errno = ENOENT;            /* not quite the right error message */
  1570. X
  1571. X    if (allocated)
  1572. X    (void) free ((char *) addr);
  1573. X    return (0);
  1574. X}
  1575. END_OF_FILE
  1576. if test 1936 -ne `wc -c <'./src/etherh2e.c'`; then
  1577.     echo shar: \"'./src/etherh2e.c'\" unpacked with wrong size!
  1578. fi
  1579. # end of './src/etherh2e.c'
  1580. fi
  1581. if test -f './src/etherhe2e.c' -a "${1}" != "-c" ; then 
  1582.   echo shar: Will not clobber existing file \"'./src/etherhe2e.c'\"
  1583. else
  1584. echo shar: Extracting \"'./src/etherhe2e.c'\" \(2146 characters\)
  1585. sed "s/^X//" >'./src/etherhe2e.c' <<'END_OF_FILE'
  1586. X/* $Id: etherhe2e.c,v 2.1 89/10/24 17:53:20 dupuy Exp $ */
  1587. X
  1588. X#include <sys/types.h>            /* in_addr (u_short) */
  1589. X#include <sys/socket.h>            /* AF_INET */
  1590. X#include <netinet/in.h>            /* in_addr */
  1591. X
  1592. X#include <netdb.h>            /* hostent */
  1593. X#include <errno.h>            /* EAFNOSUPPORT */
  1594. X
  1595. Xextern int errno;
  1596. X
  1597. X#include "libether.h"
  1598. X
  1599. X/*
  1600. X * derived from ethertools/hetoea.c
  1601. X *
  1602. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  1603. X * All Rights Reserved
  1604. X *
  1605. X * Permission is granted to any individual or institution to use, copy, or
  1606. X * redistribute this software so long as it is not sold for profit, provided
  1607. X * that this notice and the original copyright notices are retained.  Boston
  1608. X * University makes no representations about the suitability of this software
  1609. X * for any purpose.  It is provided "as is" without express or implied
  1610. X * warranty.
  1611. X */
  1612. X
  1613. Xether_addr *
  1614. Xether_hostent2e (host, addr)
  1615. Xstruct hostent *host;
  1616. Xether_addr *addr;
  1617. X{
  1618. X    char **hlist;
  1619. X    int allocated = 0;
  1620. X
  1621. X    if (addr == 0)
  1622. X    {
  1623. X    addr = (ether_addr *) malloc (sizeof (ether_addr));
  1624. X    allocated++;
  1625. X    }
  1626. X
  1627. X#if ETHERDB
  1628. X    if (ether_hostton (host->h_name, addr) == 0)
  1629. X    return (addr);            /* official name worked */
  1630. X
  1631. X    for (hlist = host->h_aliases; *hlist != 0; hlist++)
  1632. X    if (ether_hostton (*hlist, addr) == 0)
  1633. X        return (addr);
  1634. X#endif
  1635. X
  1636. X    /*
  1637. X     * Try to resolve the IP addresses if possible.  We would try this first
  1638. X     * if proxy ARP didn't cause such confusion.
  1639. X     */
  1640. X
  1641. X    if (host->h_addrtype == AF_INET)
  1642. X    {
  1643. X    struct in_addr haddr;
  1644. X    int saved_errno = 0;
  1645. X
  1646. X#ifdef h_addr                /* we have a list */
  1647. X    for (hlist = host->h_addr_list; *hlist != 0; hlist++)
  1648. X    {
  1649. X        bcopy (*hlist, (char *) &haddr, sizeof (haddr));
  1650. X#else
  1651. X        bcopy (host->h_addr, (char *) &haddr, sizeof (haddr));
  1652. X#endif
  1653. X        if (ether_ip2e (&haddr, addr))
  1654. X        return (addr);
  1655. X        else if (saved_errno == 0)
  1656. X        saved_errno = errno;
  1657. X        else if (errno == EHOSTDOWN)
  1658. X        saved_errno = errno;
  1659. X#ifdef h_addr
  1660. X    }
  1661. X#endif
  1662. X    errno = saved_errno;        /* restore "best" error message */
  1663. X    }
  1664. X    else
  1665. X    errno = EAFNOSUPPORT;        /* not quite the right error message */
  1666. X
  1667. X    if (allocated)
  1668. X    free ((char *) addr);
  1669. X
  1670. X    return (0);
  1671. X}
  1672. END_OF_FILE
  1673. if test 2146 -ne `wc -c <'./src/etherhe2e.c'`; then
  1674.     echo shar: \"'./src/etherhe2e.c'\" unpacked with wrong size!
  1675. fi
  1676. # end of './src/etherhe2e.c'
  1677. fi
  1678. if test -f './src/etherints.c' -a "${1}" != "-c" ; then 
  1679.   echo shar: Will not clobber existing file \"'./src/etherints.c'\"
  1680. else
  1681. echo shar: Extracting \"'./src/etherints.c'\" \(2675 characters\)
  1682. sed "s/^X//" >'./src/etherints.c' <<'END_OF_FILE'
  1683. X/* $Id: etherints.c,v 2.0 89/10/20 19:02:24 dupuy Exp $ */
  1684. X
  1685. X#include <strings.h>            /* strcmp */
  1686. X
  1687. X#include <sys/types.h>            /* AF_INET (u_char) */
  1688. X#include <sys/socket.h>            /* AF_INET */
  1689. X#include <net/if.h>            /* IFNAMSIZ */
  1690. X#ifdef _SOCKET_                /* 4.0 system? */
  1691. X#include <sys/sockio.h>            /* SIOCGIFCONF */
  1692. X#else
  1693. X#endif
  1694. X#include <sys/ioctl.h>            /* ioctl */
  1695. X
  1696. X#include "libether.h"
  1697. X
  1698. Xstatic char checked;            /* boolean flag */
  1699. X
  1700. Xstatic char *result[MAXNUMIF];
  1701. Xstatic char names[MAXNUMIF * IFNAMSIZ];
  1702. X#ifdef sun
  1703. Xstatic char *validname[] = {"le", "ie", "ec", 0};
  1704. X
  1705. X#endif
  1706. X#ifdef vax
  1707. Xstatic char *validname[] = {"de", "ec", "ex", "il", "ni", "qe", "se", 0};
  1708. X
  1709. X#endif
  1710. X#ifdef mips
  1711. Xstatic char *validname[] = {"ni", "qe", "se", 0};
  1712. X
  1713. X#endif
  1714. X
  1715. X
  1716. Xshort _ether_ifindex[MAXNUMIF];        /* used by _ether_localif() */
  1717. Xstruct ifconf _ether_ifconf;        /* used by _ether_localif() */
  1718. Xstatic char cbuf[MAXNUMIF * sizeof (struct ifreq)];
  1719. X
  1720. X/*
  1721. X * Returns an array of strings (with last element 0) each entry of which is an
  1722. X * ethernet interface name valid for use in ether_open().  Valid prefixes for
  1723. X * ethernet interface names are in validname.  Assumes that the device
  1724. X * prefixes are unique (i.e. no eckankar0 device exists).
  1725. X */
  1726. X
  1727. Xchar **
  1728. Xether_interfaces ()
  1729. X{
  1730. X    int sfd;
  1731. X
  1732. X    register int i;
  1733. X    register int j;
  1734. X    register int k;
  1735. X    register int l;
  1736. X    int numinter;
  1737. X
  1738. X    if (checked)
  1739. X    return (result);        /* we have alread done this */
  1740. X
  1741. X    /* we have not yet checked the interfaces */
  1742. X
  1743. X    if ((sfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
  1744. X    {
  1745. X#ifdef DEBUG
  1746. X    perror ("libether socket:");
  1747. X#endif
  1748. X    return (0);
  1749. X    }
  1750. X
  1751. X    _ether_ifconf.ifc_len = sizeof (cbuf);
  1752. X    _ether_ifconf.ifc_buf = cbuf;
  1753. X    if (ioctl (sfd, SIOCGIFCONF, (char *) &_ether_ifconf) < 0)
  1754. X    {
  1755. X#ifdef DEBUG
  1756. X    perror ("libether SIOCGIFCONF:");
  1757. X#endif
  1758. X    (void) close (sfd);
  1759. X    return (0);
  1760. X    }
  1761. X
  1762. X    k = 0;
  1763. X    numinter = _ether_ifconf.ifc_len / sizeof (struct ifreq);
  1764. X    for (i = 0; i < numinter; i++)
  1765. X    {
  1766. X    for (j = 0; validname[j] != 0; j++)
  1767. X        if (strncmp (_ether_ifconf.ifc_req[i].ifr_name,
  1768. X             validname[j], 2) == 0)
  1769. X        {
  1770. X        for (l = 0; l < k; l++)
  1771. X            if (!strcmp (result[l], _ether_ifconf.ifc_req[i].ifr_name))
  1772. X            {
  1773. X            if (_ether_ifconf.ifc_req[i].ifr_addr.sa_family
  1774. X                == AF_INET)
  1775. X                _ether_ifindex[l] = i;
  1776. X
  1777. X            goto duplicate;
  1778. X            }
  1779. X
  1780. X        (void) strncpy (names + IFNAMSIZ * k,
  1781. X                _ether_ifconf.ifc_req[i].ifr_name, IFNAMSIZ);
  1782. X        result[k] = names + IFNAMSIZ * k;
  1783. X        if (_ether_ifconf.ifc_req[i].ifr_addr.sa_family == AF_INET)
  1784. X            _ether_ifindex[k] = i;
  1785. X        else
  1786. X            _ether_ifindex[k] = -1;
  1787. X        ++k;
  1788. X        }
  1789. X      duplicate:
  1790. X    ;
  1791. X    }
  1792. X    result[k] = 0;
  1793. X
  1794. X
  1795. X    (void) close (sfd);
  1796. X    checked = 1;
  1797. X    return (result);
  1798. X}
  1799. END_OF_FILE
  1800. if test 2675 -ne `wc -c <'./src/etherints.c'`; then
  1801.     echo shar: \"'./src/etherints.c'\" unpacked with wrong size!
  1802. fi
  1803. # end of './src/etherints.c'
  1804. fi
  1805. if test -f './src/etherip2e.c' -a "${1}" != "-c" ; then 
  1806.   echo shar: Will not clobber existing file \"'./src/etherip2e.c'\"
  1807. else
  1808. echo shar: Extracting \"'./src/etherip2e.c'\" \(4804 characters\)
  1809. sed "s/^X//" >'./src/etherip2e.c' <<'END_OF_FILE'
  1810. X/* $Id: etherip2e.c,v 2.1 89/10/24 17:53:25 dupuy Exp $ */
  1811. X
  1812. X#include <sys/types.h>            /* in_addr (u_short) */
  1813. X#include <sys/ioctl.h>            /* ioctl */
  1814. X#include <sys/errno.h>            /* ENXIO */
  1815. X#include <sys/time.h>            /* timeval */
  1816. X#include <sys/socket.h>            /* sockaddr */
  1817. X#ifdef _SOCKET_                /* 4.0 system? */
  1818. X#include <sys/sockio.h>            /* SIOCGCONF */
  1819. X#include <net/if_arp.h>            /* arpreq */
  1820. X#endif
  1821. X#include <net/if.h>            /* ifreq */
  1822. X#include <netinet/in.h>            /* in_addr */
  1823. X
  1824. X#ifndef FD_SETSIZE
  1825. X#define fd_set int
  1826. X#else
  1827. X#if defined (ultrix) && defined (lint)
  1828. X#define fd_set int
  1829. X#endif
  1830. X#endif
  1831. X
  1832. X#ifndef IPPORT_DISCARD
  1833. X#define IPPORT_DISCARD 9        /* not worth looking up in services */
  1834. X#endif
  1835. X
  1836. X#include "libether.h"
  1837. X
  1838. X/*
  1839. X * derived from ethertools/iptoea.c
  1840. X *
  1841. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  1842. X * All Rights Reserved
  1843. X *
  1844. X * Permission is granted to any individual or institution to use, copy, or
  1845. X * redistribute this software so long as it is not sold for profit, provided
  1846. X * that this notice and the original copyright notices are retained.  Boston
  1847. X * University makes no representations about the suitability of this software
  1848. X * for any purpose.  It is provided "as is" without express or implied
  1849. X * warranty.
  1850. X */
  1851. X
  1852. Xextern int errno;
  1853. X
  1854. Xether_addr *
  1855. Xether_ip2e (ipaddr, addr)
  1856. Xstruct in_addr *ipaddr;
  1857. Xether_addr *addr;
  1858. X{
  1859. X    int sockfd;
  1860. X    char cbuf[MAXNUMIF * sizeof (struct ifreq)];
  1861. X    struct sockaddr_in *sin;
  1862. X    struct arpreq arp;
  1863. X    struct timeval tv;
  1864. X    struct ifconf ifc;
  1865. X    int allocated = 0;
  1866. X    int numinter;
  1867. X    int saved_errno;
  1868. X    int i;
  1869. X
  1870. X    if (addr == 0)
  1871. X    {
  1872. X    addr = (ether_addr *) malloc (sizeof (ether_addr));
  1873. X    allocated++;
  1874. X    }
  1875. X
  1876. X    if (addr == 0)
  1877. X    return (0);
  1878. X
  1879. X    if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
  1880. X    {
  1881. X    saved_errno = errno;
  1882. X#ifdef DEBUG
  1883. X    perror ("ether_ip2e: socket");
  1884. X#endif
  1885. X    goto failed2open;
  1886. X    }
  1887. X
  1888. X    arp.arp_ha.sa_family = AF_UNSPEC;
  1889. X    arp.arp_pa.sa_family = AF_INET;
  1890. X    sin = (struct sockaddr_in *) &arp.arp_pa;
  1891. X    bcopy ((char *) ipaddr, (char *) &sin->sin_addr, sizeof (*ipaddr));
  1892. X    sin->sin_port = htons (IPPORT_DISCARD);
  1893. X
  1894. X    /*
  1895. X     * First, check the arp table once.
  1896. X     */
  1897. X
  1898. X    if (!ioctl (sockfd, SIOCGARP, (char *) &arp) && arp.arp_flags & ATF_COM)
  1899. X    {
  1900. X    bcopy (arp.arp_ha.sa_data, (char *) addr, sizeof (*addr));
  1901. X    (void) close (sockfd);
  1902. X    return (addr);
  1903. X    }
  1904. X
  1905. X    /*
  1906. X     * Then force a kernel ARP resolution by sending a datagram to the IP
  1907. X     * host. The MSG_DONTROUTE flag prevents the kernel from using a route to
  1908. X     * another IP network (which would not be reachable at the ethernet
  1909. X     * level).    We use the discard service to avoid complications.
  1910. X     */
  1911. X
  1912. X    if (sendto (sockfd, (char *) &sockfd, 1, MSG_DONTROUTE,
  1913. X        (struct sockaddr *) sin, sizeof (*sin)) < 0)
  1914. X    {
  1915. X    saved_errno = errno;
  1916. X
  1917. X#ifdef DEBUG
  1918. X    perror ("ether_ip2e: sendto");
  1919. X#endif
  1920. X    goto failed;
  1921. X    }
  1922. X
  1923. X    /*
  1924. X     * Now loop for a short while (.5 - 1.0 sec) looking for the ARP entry.
  1925. X     */
  1926. X
  1927. X    tv.tv_sec = 0;
  1928. X    tv.tv_usec = 100000;        /* .1 second */
  1929. X
  1930. X    for (i = 0; i < 10; i++)
  1931. X    {
  1932. X    if (ioctl (sockfd, SIOCGARP, (char *) &arp) < 0)
  1933. X    {
  1934. X        if (errno != ENXIO)        /* unexpected error */
  1935. X        {
  1936. X        saved_errno = errno;
  1937. X#ifdef DEBUG
  1938. X        perror ("ether_ip2e: ioctl (SIOCGARP)");
  1939. X#endif
  1940. X        goto failed;
  1941. X        }
  1942. X
  1943. X        /*
  1944. X         * Penalize for no entry yet (wait longer if incomplete found).
  1945. X         */
  1946. X
  1947. X        i++;
  1948. X    }
  1949. X    else if (arp.arp_flags & ATF_COM)
  1950. X    {
  1951. X        bcopy (arp.arp_ha.sa_data, (char *) addr, sizeof (*addr));
  1952. X        (void) close (sockfd);
  1953. X        return (addr);
  1954. X    }
  1955. X
  1956. X    (void) select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv);
  1957. X    }
  1958. X
  1959. X    /*
  1960. X     * As a last resort, since arp tables don't keep entries for the local
  1961. X     * interfaces, we scan the local interfaces to check for a match.
  1962. X     */
  1963. X
  1964. X    ifc.ifc_len = sizeof (cbuf);
  1965. X    ifc.ifc_buf = cbuf;
  1966. X    if (ioctl (sockfd, SIOCGIFCONF, (char *) &ifc) < 0)
  1967. X    {
  1968. X#ifdef DEBUG
  1969. X    perror ("libether SIOCGIFCONF:");
  1970. X#endif
  1971. X    goto failed;
  1972. X    }
  1973. X
  1974. X    (void) close (sockfd);
  1975. X
  1976. X    numinter = ifc.ifc_len / sizeof (struct ifreq);
  1977. X    for (i = 0; i < numinter; i++)
  1978. X    {
  1979. X    struct sockaddr_in *inaddr;
  1980. X
  1981. X    if (ifc.ifc_req[i].ifr_addr.sa_family == AF_INET)
  1982. X    {
  1983. X        inaddr = (struct sockaddr_in *) &ifc.ifc_req[i].ifr_addr;
  1984. X        if (ipaddr->s_addr == inaddr->sin_addr.s_addr)
  1985. X        {
  1986. X
  1987. X        /*
  1988. X         * The IP address given corresponds to a local interface; get
  1989. X         * the ethernet address for that interface if possible;
  1990. X         */
  1991. X
  1992. X        if (ether_intfaddr (ifc.ifc_req[i].ifr_name, addr) == 0)
  1993. X        {
  1994. X            saved_errno = errno;
  1995. X            goto failed2open;
  1996. X        }
  1997. X
  1998. X        return (addr);        /* got the address - we're done */
  1999. X        }
  2000. X    }
  2001. X    }
  2002. X
  2003. X    saved_errno = EHOSTDOWN;
  2004. X    goto failed2open;
  2005. X
  2006. X  failed:
  2007. X
  2008. X    (void) close (sockfd);
  2009. X
  2010. X  failed2open:
  2011. X
  2012. X    if (allocated)
  2013. X    free ((char *) addr);
  2014. X
  2015. X    errno = saved_errno;
  2016. X    return (0);
  2017. X}
  2018. END_OF_FILE
  2019. if test 4804 -ne `wc -c <'./src/etherip2e.c'`; then
  2020.     echo shar: \"'./src/etherip2e.c'\" unpacked with wrong size!
  2021. fi
  2022. # end of './src/etherip2e.c'
  2023. fi
  2024. if test -f './tests/ctp.h' -a "${1}" != "-c" ; then 
  2025.   echo shar: Will not clobber existing file \"'./tests/ctp.h'\"
  2026. else
  2027. echo shar: Extracting \"'./tests/ctp.h'\" \(3080 characters\)
  2028. sed "s/^X//" >'./tests/ctp.h' <<'END_OF_FILE'
  2029. X/* $Id: ctp.h,v 1.2 89/10/24 17:54:33 dupuy Exp $ */
  2030. X
  2031. X/*
  2032. X * derived from ethertools/ctp.h
  2033. X * 
  2034. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University All
  2035. X * Rights Reserved
  2036. X * 
  2037. X * Permission is granted to any individual or institution to use, copy, or
  2038. X * redistribute this software so long as it is not sold for profit, provided
  2039. X * that this notice and the original copyright notices are retained.  Boston
  2040. X * University makes no representations about the suitability of this software
  2041. X * for any purpose.  It is provided "as is" without express or implied
  2042. X * warranty.
  2043. X */
  2044. X
  2045. X/*
  2046. X * Make sure we have the fd_set macros
  2047. X */
  2048. X
  2049. X#ifndef FD_SETSIZE
  2050. X#define FD_SETSIZE 256            /* Ultrix uses a chintzy 64 */
  2051. X#endif
  2052. X
  2053. X#include <sys/param.h>
  2054. X
  2055. X#ifndef FD_SET                /* no fd_set macros in sys/types.h */
  2056. X
  2057. X#if NOFILE > 32                /* assumes we included sys/param.h */
  2058. X
  2059. X#ifndef NBBY
  2060. X#define NBBY    8            /* number of bits in a byte */
  2061. X#endif
  2062. X
  2063. Xtypedef long fd_mask;
  2064. X#define NFDBITS (sizeof(fd_mask) * NBBY)/* bits per mask */
  2065. X#ifndef howmany
  2066. X#define howmany(x, y)    (((x)+((y)-1))/(y))
  2067. X#endif
  2068. X
  2069. X#define fd_set real_fd_set
  2070. X
  2071. Xtypedef struct real_fd_set
  2072. X{
  2073. X    fd_mask fds_bits[howmany (FD_SETSIZE, NFDBITS)];
  2074. X}           real_fd_set;
  2075. X
  2076. X#define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  2077. X#define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  2078. X#define FD_ISSET(n, p)    ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  2079. X#define FD_ZERO(p)    bzero((char *)(p), sizeof(*(p)))
  2080. X
  2081. X#define param(s)    ((int *) (s))
  2082. X
  2083. X#else                    /* NOFILE <= 32 */
  2084. X
  2085. X/*
  2086. X * Create the fd_set type, just in case this isn't 4.2.
  2087. X */
  2088. X
  2089. X#define fd_set real_fd_set
  2090. X
  2091. Xtypedef struct real_fd_set
  2092. X{
  2093. X    long fds_bits[1];
  2094. X}           real_fd_set;
  2095. X
  2096. X#define FD_SET(f,s)    ((s)->fds_bits[0] |= (1 << (f)))
  2097. X#define FD_CLR(f,s)    ((s)->fds_bits[0] &= ~(1 << (f)))
  2098. X#define FD_ISSET(f,s)    ((s)->fds_bits[0] & (1 << (f)))
  2099. X#define FD_ZERO(s)    ((s)->fds_bits[0] = 0)
  2100. X
  2101. X#define param(s)    ((int *) (s))
  2102. X
  2103. X#endif                    /* NOFILE > 32 */
  2104. X
  2105. X#else
  2106. X
  2107. X#define param(s)    ((fd_set *) (s))
  2108. X
  2109. X#endif                    /* FD_SET */
  2110. X
  2111. X/*
  2112. X * CTP Protocol constants
  2113. X */
  2114. X
  2115. X#define CTPTYPE 0x9000
  2116. X
  2117. X#define CTP_REP 1            /* in VAX byte order */
  2118. X#define CTP_FWD 2
  2119. X
  2120. X/*
  2121. X * CTP packet structures
  2122. X */
  2123. X
  2124. X#include <sys/time.h>
  2125. X#include "ether.h"
  2126. X
  2127. Xtypedef struct ctppacket        /* CTP packet layout */
  2128. X{
  2129. X    int :0;                /* force long alignment for timeval */
  2130. X    unsigned short skip;        /* CTP skip in VAX byte order */
  2131. X
  2132. X    char data[ETHER_MAX - sizeof (unsigned short)];
  2133. X}
  2134. X          ctp_packet;
  2135. X
  2136. Xtypedef struct ctpforward        /* forward subpacket */
  2137. X{
  2138. X    unsigned short function;        /* CTP_FWD */
  2139. X    ether_addr addr;
  2140. X}
  2141. X           ctp_forward;
  2142. X
  2143. Xtypedef struct ctpreply            /* reply subpacket */
  2144. X{
  2145. X    unsigned short function;        /* CTP_REP */
  2146. X
  2147. X    /* The following is data that we use for own purposes */
  2148. X
  2149. X    unsigned short pid;            /* pid of sender -- not swapped */
  2150. X    unsigned short seq;            /* sequence number -- not swapped */
  2151. X
  2152. X    short sendt[4];            /* really struct timeval */
  2153. X}
  2154. X         ctp_reply;
  2155. X
  2156. X#define MAXPATH ((ETHER_MAX - sizeof (ctp_reply) - 2)  / sizeof (ctp_forward))
  2157. END_OF_FILE
  2158. if test 3080 -ne `wc -c <'./tests/ctp.h'`; then
  2159.     echo shar: \"'./tests/ctp.h'\" unpacked with wrong size!
  2160. fi
  2161. # end of './tests/ctp.h'
  2162. fi
  2163. echo shar: End of archive 2 \(of 3\).
  2164. cp /dev/null ark2isdone
  2165. MISSING=""
  2166. for I in 1 2 3 ; do
  2167.     if test ! -f ark${I}isdone ; then
  2168.     MISSING="${MISSING} ${I}"
  2169.     fi
  2170. done
  2171. if test "${MISSING}" = "" ; then
  2172.     echo You have unpacked all 3 archives.
  2173.     rm -f ark[1-9]isdone
  2174. else
  2175.     echo You still need to unpack the following archives:
  2176.     echo "        " ${MISSING}
  2177. fi
  2178. ##  End of shell archive.
  2179. exit 0
  2180.